package rise.ui;

import java.util.Collection;
import java.util.LinkedList;

import org.osmdroid.DefaultResourceProxyImpl;
import org.osmdroid.ResourceProxy;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapController;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.ItemizedIconOverlay;
import org.osmdroid.views.overlay.ItemizedIconOverlay.OnItemGestureListener;
import org.osmdroid.views.overlay.OverlayItem;
import org.osmdroid.views.overlay.ScaleBarOverlay;

import rise.comunity.Community;
import rise.comunity.GPSLocation;
import rise.comunity.Status;
import rise.comunity.UserData;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.widget.Toast;

public class MapActivity extends RiseActivity {
	private MapView openMapView;
	private MapController mapController;

	private ItemizedIconOverlay<OverlayItem> itemizedIconOverlay;
	private ItemizedIconOverlay<OverlayItem> selfItemizedIconOverlay;
	private boolean alreadyTold = false;
	private LocationManager locationManager;
	private LocationListener locationListener;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_map);
		MapActivity.mapActivity = this;

		locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		locationListener = new LocationListener() {
			public void onLocationChanged(Location loc) {
			}

			public void onStatusChanged(String provider, int status,
					Bundle extras) {
			}

			public void onProviderEnabled(String provider) {
			}

			public void onProviderDisabled(String provider) {
			}
		};

		locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0,
				0, locationListener);
		Location lastLocation = locationManager
				.getLastKnownLocation(LocationManager.GPS_PROVIDER);

		this.setUp();
		this.populate();
		
		if (lastLocation != null) {
			mapController.setCenter(new GeoPoint(lastLocation));
		} else if (!alreadyTold) {
			showNoGpsDialog();
		}
	}

	OnItemGestureListener<OverlayItem> selfGestureListener = new OnItemGestureListener<OverlayItem>() {

		@Override
		public boolean onItemLongPress(int arg0, OverlayItem arg1) {
			Intent intent = new Intent(MapActivity.this, Conversation.class);
			intent.putExtra("username", Community.broadcastWildcard);
			MapActivity.this.startActivity(intent);

			return true;
		}

		@Override
		public boolean onItemSingleTapUp(int arg0, OverlayItem item) {
			Toast.makeText(
					MapActivity.this,
					item.mDescription + "\n" + item.mTitle + "\n"
							+ item.mGeoPoint.getLatitudeE6() + " : "
							+ item.mGeoPoint.getLongitudeE6(),
					Toast.LENGTH_SHORT).show();
			return true;
		}

	};

	OnItemGestureListener<OverlayItem> otherUserGestureListener = new OnItemGestureListener<OverlayItem>() {

		@Override
		public boolean onItemLongPress(int arg0, OverlayItem arg1) {
			Intent intent = new Intent(MapActivity.this, Conversation.class);
			intent.putExtra("username", arg1.mDescription);
			MapActivity.this.startActivity(intent);

			return true;
		}

		@Override
		public boolean onItemSingleTapUp(int index, OverlayItem item) {
			Toast.makeText(
					MapActivity.this,
					item.mDescription + "\n" + item.mTitle + "\n"
							+ item.mGeoPoint.getLatitudeE6() + " : "
							+ item.mGeoPoint.getLongitudeE6(),
					Toast.LENGTH_SHORT).show();

			return true;
		}

	};

	private Drawable getDrawable() {
		Drawable marker = getResources().getDrawable(R.drawable.map_blue_30);
		int markerWidth = marker.getIntrinsicWidth();
		int markerHeight = marker.getIntrinsicHeight();
		marker.setBounds(0, markerHeight, markerWidth, 0);
		return marker;
	}

	private Drawable getSelfDrawable() {
		Drawable marker = getResources().getDrawable(R.drawable.map_pin);
		int markerWidth = marker.getIntrinsicWidth();
		int markerHeight = marker.getIntrinsicHeight();
		marker.setBounds(0, markerHeight, markerWidth, 0);
		return marker;
	}

	private void setUp() {
		openMapView = (MapView) findViewById(R.id.openmapview);
		openMapView.setBuiltInZoomControls(true);
		mapController = openMapView.getController();
		mapController.setZoom(5);

		ResourceProxy resourceProxy = new DefaultResourceProxyImpl(
				getApplicationContext());
		itemizedIconOverlay = new ItemizedIconOverlay<OverlayItem>(
				new LinkedList<OverlayItem>(), getDrawable(),
				otherUserGestureListener, resourceProxy);
		selfItemizedIconOverlay = new ItemizedIconOverlay<OverlayItem>(
				new LinkedList<OverlayItem>(), getSelfDrawable(),
				selfGestureListener, resourceProxy);
		openMapView.getOverlays().add(itemizedIconOverlay);
		openMapView.getOverlays().add(selfItemizedIconOverlay);

		ScaleBarOverlay myScaleBarOverlay = new ScaleBarOverlay(this);
		openMapView.getOverlays().add(myScaleBarOverlay);
		openMapView.invalidate();
	}

	private void resetOverlay() {
		openMapView.getOverlays().remove(itemizedIconOverlay);
		openMapView.getOverlays().remove(selfItemizedIconOverlay);

		ResourceProxy resourceProxy = new DefaultResourceProxyImpl(
				getApplicationContext());
		itemizedIconOverlay = new ItemizedIconOverlay<OverlayItem>(
				new LinkedList<OverlayItem>(), getDrawable(),
				otherUserGestureListener, resourceProxy);
		selfItemizedIconOverlay = new ItemizedIconOverlay<OverlayItem>(
				new LinkedList<OverlayItem>(), getSelfDrawable(),
				selfGestureListener, resourceProxy);
		openMapView.getOverlays().add(itemizedIconOverlay);
		openMapView.getOverlays().add(selfItemizedIconOverlay);
	}

	private void populate() {
		resetOverlay();
		locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0,
				0, locationListener);
		Location lastLocation = locationManager
				.getLastKnownLocation(LocationManager.GPS_PROVIDER);

		if (lastLocation != null) {
			GeoPoint myPoint0 = new GeoPoint(lastLocation);
			UserData userData = UserData.obtainUserData();
			selfItemizedIconOverlay.addItem(new OverlayItem(userData
					.getStatus().toString(), userData.getUsername(), myPoint0));
		} else if (!alreadyTold) {
			showNoGpsDialog();
		}

		Community community = Community.obtainCommunity();
		Collection<String> onlineUsers = community.getOnlineUsers();
		for (String currentUser : onlineUsers) {
			GPSLocation gpsLocation = community.getUserGPSLocation(currentUser);
			itemizedIconOverlay.addItem(new OverlayItem(community
					.getUserStatus(currentUser).toString(), currentUser,
					new GeoPoint(gpsLocation.getLat(), gpsLocation.getLon())));
		}
		openMapView.invalidate();
	}

	private void showNoGpsDialog() {
		AlertDialog.Builder noGpsDialog = new AlertDialog.Builder(this);
		noGpsDialog.setTitle("GPS non rilevato");

		noGpsDialog.setPositiveButton("Ok",
				new DialogInterface.OnClickListener() {

					public void onClick(DialogInterface arg0, int arg1) {
					}
				});

		noGpsDialog.show();
		this.alreadyTold = true;
	}

	@Override
	protected void onResume() {
		super.onResume();
		this.alreadyTold = false;
		this.populate();
	}

	@Override
	protected void onRestart() {
		super.onRestart();
		this.alreadyTold = false;
		this.populate();
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);
		menu.findItem(R.id.menu_map).setVisible(false);
		return true;
	}

	private static MapActivity mapActivity;
	public static MapRefreshHandler handler = null;

	public static void RefreshMapActivity() {
		if (mapActivity == null)
			return;
		mapActivity.populate();
	}
}